package com.sangmo.fts.process.factoring.service;

import com.sangmo.boot.framework.common.errors.ServiceException;
import com.sangmo.boot.framework.common.errors.StandardErrors;
import com.sangmo.boot.framework.data.filter.PageResult;
import com.sangmo.boot.framework.data.filter.PageSearch;
import com.sangmo.boot.framework.data.filter.ValueFilter;
import com.sangmo.boot.framework.plugin.dataview.crud.service.DelegateViewService;
import com.sangmo.boot.framework.plugin.dataview.crud.service.ViewService;
import com.sangmo.fts.common.utils.RandomUtils;
import com.sangmo.fts.process.factoring.interfaces.FfLoanAcceptRequest;
import com.sangmo.fts.process.factoring.model.FfLoan;
import com.sangmo.fts.process.inventory.model.IfLoan;
import com.sangmo.fts.process.receivable.model.RpfLoan;
import com.sangmo.fts.process.storage.model.CsfLoan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Service
@Transactional
public class FfLoanService extends DelegateViewService<FfLoan> {

    @Autowired
    private FfLoanEntityService ffLoanEntityService;

    @Override
    protected ViewService<FfLoan> getEntityService() {
        return ffLoanEntityService;
    }

    public void accept(Long id, FfLoanAcceptRequest request) {
        FfLoan loan = this.get(id);
        if (!FfLoan.States.ACCEPTING.equals(loan.getState())) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.ffLoan.accept.state.wrong");
        }
        loan.setState(FfLoan.States.PENDING);
        loan.setApprovedAmount(request.getApprovedAmount());
        loan.setAcceptCode(RandomUtils.generateRandomNum(10));
        this.save(loan);
    }

    public FfLoan findByWaybillId(Long waybillId) {
        return ffLoanEntityService.findByWaybillId(waybillId);
    }

    public void issue(Long id) {
        FfLoan loan = this.get(id);
        if (!FfLoan.States.CONFIRMED.equals(loan.getState())) {
            throw new ServiceException(StandardErrors.CLIENT_ERROR.getStatus(), "error.ffLoan.issue.state.wrong");
        }
        loan.setCode(RandomUtils.generateRandomNum(10));
        loan.setIssueState(FfLoan.IssueStates.COMPLETED);
        this.save(loan);
    }

    public PageResult<FfLoan> selection(PageSearch ps) {
        ps.getFilters().add(new ValueFilter("state", ValueFilter.OP_EQ, FfLoan.States.PENDING));
        return super.search(ps);
    }

    public PageResult<FfLoan> repaymentSelection(PageSearch ps) {
        ps.getFilters().add(new ValueFilter("state", ValueFilter.OP_EQ, FfLoan.States.CONFIRMED));
        return super.search(ps);
    }

    public void transferApplyBuyerConfirm(Long loanId) {
        FfLoan loan = this.get(loanId);
        if (FfLoan.States.PENDING.equals(loan.getState())) {
            loan.setState(FfLoan.States.CONFIRMED);
            this.save(loan);
        }
    }

    public void settle(Long loanId, BigDecimal amount) {
        FfLoan loan = this.get(loanId);
        if (loan.getAmount().compareTo(amount) <= 0) {
            loan.setSettled(true);
            this.save(loan);
        }
    }

}
